using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace DynamicGeneration.Modules.WebApiExplorer
{
    public class RouteGraph : RouteInfo
    {
        public List<KeyValuePair<string, object>> DataTokens { get; set; }
        public List<KeyValuePair<string, object>> Constraints { get; set; }
        public List<KeyValuePair<string, object>> Defaults { get; set; }
        public List<ControllerInfo> Controllers { get; set; }

        public RouteGraph(System.Web.Routing.Route route)
        {
            if (route == null)
                throw new ArgumentNullException("route", "route is null.");
            UrlPattern = route.Url;
            RouteName = route.DataTokens.ContainsKey("name") ? route.DataTokens["name"].ToString() : null;
            ControllerNamespaces = route.DataTokens.ContainsKey("namespaces") ? route.DataTokens["namespaces"] as string[] : null;
            RouteHandler = route.RouteHandler.GetType().Name;

            DataTokens = route.DataTokens.ToList<KeyValuePair<string, object>>();
            Constraints = route.Constraints.ToList<KeyValuePair<string, object>>();
            Defaults = route.Defaults.ToList<KeyValuePair<string, object>>();

            if (DataTokens == null)
                DataTokens = new List<KeyValuePair<string, object>>();
            if (Constraints == null)
                Constraints = new List<KeyValuePair<string, object>>();
            if (Defaults == null)
                Defaults = new List<KeyValuePair<string, object>>();

            Controllers = new List<ControllerInfo>();
            foreach (var cns in ControllerNamespaces)
            {
                var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
                foreach (var asmbly in loadedAssemblies)
                    foreach (var item in GetTypesInNamespace(asmbly, cns))
                        if (item.Name.EndsWith("Controller"))
                            Controllers.Add(new ControllerInfo(item) { });
            }
        }
        private Type[] GetTypesInNamespace(Assembly assembly, string nameSpace)
        {
            return assembly.GetTypes().Where(t => String.Equals(t.Namespace, nameSpace, StringComparison.Ordinal)).ToArray();
        }
    }
}
